/* board_init.c */
#include "board_init.h"

void BOARD_InitDebugConsole(void);

void BOARD_Init(void)
{
    BOARD_InitBootClocks();
    BOARD_InitBootPins();
    
	BOARD_InitDebugConsole();
    
    /* enable the dma controller. */
    DMA_ControllerInit_Type dma_init;
    dma_init.EnableContinuousLinkMode = false;
    dma_init.EnableKeepTransOnDebug = true;
    dma_init.EnableMinorLoopOffset = false;
    DMA_InitController(DMA, &dma_init);
}

void BOARD_InitDebugConsole(void)
{
    UART_Init_Type uart_init;
    
    uart_init.SrcClkFreq = BOARD_DEBUG_UART_CLK_SRC_HZ;
    uart_init.Baudrate   = BOARD_DEBUG_UART_BAUDRATE;
    uart_init.DataBits   = UART_DataBits_8b;
    uart_init.StopBits   = UART_StopBits_1b;
    uart_init.IdleSize   = UART_IdleSize_1B;
    uart_init.Parity     = UART_Parity_None;
    uart_init.TxFifoWatermark = 1u;
    uart_init.RxFifoWatermark = 1u; /* use rx watermark flag as the rx available flag. */
    
    UART_Init(BOARD_DEBUG_UART_PORT, &uart_init);
}

void BOARD_PutChar(uint8_t c)
{
    while (0u == (UART_FLAG_TX_REQ & UART_GetStatusFlags(BOARD_DEBUG_UART_PORT) ) )
    {
    }
    UART_PutTxFifoData(BOARD_DEBUG_UART_PORT, c);
}

uint8_t BOARD_GetChar(void)
{
    while (0u == (UART_FLAG_RX_REQ & UART_GetStatusFlags(BOARD_DEBUG_UART_PORT) ) )
    {
    }
    return UART_GetRxFifoData(BOARD_DEBUG_UART_PORT);
}

#if defined(__ARMCC_VERSION)
int fputc(int c, FILE *f)
{
    (void)(f);

    BOARD_PutChar(c);
    
    return c;
}

int fgetc(FILE *f)
{
    (void)(f);

    return BOARD_GetChar();
}

#elif defined(__GNUC__)

/*
 * Called by libc stdio fwrite functions
 */
int _write(int fd, char *ptr, int len)
{
    int i = 0;

    /*
     * write "len" of char from "ptr" to file id "fd"
     * Return number of char written.
     *
    * Only work for STDOUT, STDIN, and STDERR
     */
    if (fd > 2)
    {
        return -1;
    }

    while (*ptr && (i < len))
    {

        BOARD_PutChar((uint8_t)(*ptr));

        i++;
        ptr++;
    }

    return i;
}

/*
 * Called by the libc stdio fread fucntions
 *
 * Implements a buffered read with line editing.
 */
int _read(int fd, char *ptr, int len)
{
    int my_len;

    if (fd > 2)
    {
        return -1;
    }

    my_len = 0;
    while (len > 0)
    {        
        *ptr = BOARD_GetChar();

        len--;
        my_len++;

        if ( (*ptr == '\r') || (*ptr == '\n') || (*ptr == '\0') )
        {
            break;
        }

        ptr++;
    }

    return my_len; /* return the length we got */
}


int putchar(int c)
{
    BOARD_PutChar(c);

    return c;
}

int getchar(void)
{
    return BOARD_GetChar();
}

#elif (defined(__ICCARM__))
/* These function __write and __read is used to support IAR toolchain to printf and scanf. */

int fputc(int ch, FILE *f)
{
    BOARD_PutChar(ch);

    return ch;
}

int fgetc(FILE *f)
{
    return BOARD_GetChar();
}

#endif




/* EOF. */

